"""
需求：创建参数服务端并操作数据
流程：
    1.导包
    2.初始化ROS2客户端
    3.自定义节点类：
      3-1.增
      3-2.查
      3-3.改
      3-4.删
    4.调用spin函数，传入自定义类对象指针，
    spin又称回旋函数，当执行到spin时，又会回去执行一次函数，而不是退出，可以理解为for语句
    5.释放资源
"""
 
# 1.导包
import rclpy
from rclpy.node import Node
 
# 3.自定义节点类: 
class ParamServer(Node):
    def __init__(self):
        ## 如果允许删除参数，需要提前声明
        super().__init__("param_server_node_py",allow_undeclared_parameters=True)
        self.get_logger().info("参数服务端，启动...")
    # 3-1.增
    def declare_param(self):
        self.get_logger().info("---- 新增参数 ----")
        self.declare_parameter("car_name","tiger")
        self.declare_parameter("width",1.55)
        self.declare_parameter("wheels",5)

        # 使用 set_parameters 函数时，要保证 allow_undeclared_parameters 为 True
        self.set_parameters([rclpy.Parameter("haha",value="xixi")])

    # 3-2.查
    def get_param(self):
        self.get_logger().info("---- 查询参数 ----")
        # 获取指定参数
        self.get_logger().info("------获取指定参数")
        car_name = self.get_parameter("car_name")
        self.get_logger().info("%s = %s" % (car_name.name,car_name.value))

        # 获取多个参数
        self.get_logger().info("------获取多个参数")
        params = self.get_parameters(["car_name","wheels","widt"])
        for param in params:
            self.get_logger().info("%s ====== %s " % (param.name,param.value))

        # 判断是否包含某个参数
        self.get_logger().info("------是否包含某个参数")
        self.get_logger().info("包含 car_name 吗？%d" % self.has_parameter("car_name"))
        self.get_logger().info("包含 height 吗？%d" % self.has_parameter("height"))

    # 3-3.改
    def update_param(self):
        self.get_logger().info("---- 修改参数 ----")

        # 获取 car_name、width 值
        car_name = self.get_parameter("car_name")
        width = self.get_parameter("width")
        # 打印修改前值
        self.get_logger().info("修改前: %s = %s" % (car_name.name, car_name.value))
        self.get_logger().info("修改前: %s = %s" % (width.name, width.value))

        # 修改单个参数
        # self.set_parameters([rclpy.Parameter("car_name", value="Mouse")]) 
        # 修改多个参数
        self.set_parameters([rclpy.Parameter("car_name",value="Mouse"),rclpy.Parameter("width",value=2.00)])

        # 获取 car_name、width 修改后的值
        car_name = self.get_parameter("car_name")
        width = self.get_parameter("width")
        # 打印修改后值
        self.get_logger().info("修改后:  %s = %s" % (car_name.name, car_name.value))
        self.get_logger().info("修改后:  %s = %s" % (width.name, width.value))

    # 3-4.删
    def del_param(self):
        self.get_logger().info("---- 删除参数 ----")
        # 输出： 1(包含)，0(不包含)
        self.get_logger().info("删除前,包含 car_name 吗？%d" % self.has_parameter("car_name"))
        """ 
            python 中 删除 car_name 不区分是 declare_parameter 或 set_parameters
            设置的键，都可以删除
        """
        self.undeclare_parameter("car_name")
        self.get_logger().info("删除后,包含 car_name 吗？%d" % self.has_parameter("car_name"))
 
 
def main():
    # 2.初始化ROS2客户端
    rclpy.init()
 
    # 4.调用spin函数，传入自定义类对象指针，
    node = ParamServer()
    node.declare_param()
    node.get_param()
    node.update_param()
    node.del_param()
    rclpy.spin(node)
 
    # 5.释放资源
    rclpy.shutdown()
 
if __name__ == '__main__':
    main()